package com.sim.simserial.ui.print

import android.app.PendingIntent
import android.content.BroadcastReceiver
import android.content.Context
import android.content.Intent
import android.content.IntentFilter
import android.hardware.usb.UsbDevice
import android.hardware.usb.UsbManager
import android.os.Parcelable
import androidx.fragment.app.viewModels
import androidx.lifecycle.viewModelScope
import com.drake.net.utils.TipUtils.toast
import com.infinit.selfhelp.common.base.ViewBindingFragment
import com.infinit.selfhelp.common.ext.onDefaultThread
import com.print.printusb.UsbDriverManager
import com.print.printusb.contant.Constant.ACTION_USB_PERMISSION
import com.print.printusb.msprintsdk.PrintCmd
import com.print.printusb.msprintsdk.PrintCmd.PrintFeedDot
import com.sim.simserial.R
import com.sim.simserial.databinding.FragmentPrintBinding
import com.sim.simserial.viewmodel.SimViewModel
import dagger.hilt.android.AndroidEntryPoint
import kotlinx.coroutines.launch
import javax.inject.Inject

@AndroidEntryPoint
class PrintFragment : ViewBindingFragment<FragmentPrintBinding>(R.layout.fragment_print) {

    @Inject
    lateinit var usbDriverManager: UsbDriverManager

    private val adminViewModel by viewModels<SimViewModel>()
    var mUsbDevice: UsbDevice? = null
    override fun initData() {
        super.initData()

    }

    override fun initView() {
        super.initView()
        mBinding.topTitle.tvTitle.text = "print"

        val permissionIntent = PendingIntent.getBroadcast(requireActivity(), 0, Intent(ACTION_USB_PERMISSION), PendingIntent.FLAG_IMMUTABLE)
        usbDriverManager.mUsbDriver?.setPermissionIntent(permissionIntent)


        // Broadcast listen for new devices
        val filter = IntentFilter()
        filter.addAction(UsbManager.ACTION_USB_DEVICE_DETACHED)
        filter.addAction(ACTION_USB_PERMISSION)
        requireActivity().registerReceiver(mUsbReceiver, filter)


    }

    override fun onEvent() {
        mBinding.topTitle.imgBack.setOnClickListener(back)
        mBinding.tvPrint.setOnClickListener {
            val iDriverCheck = usbDriverCheck()
            if (iDriverCheck == -1) {
                toast("Printer not connected!")
                return@setOnClickListener
            }

            if (iDriverCheck == 1) {
                toast("Printer unauthorized!")
                return@setOnClickListener
            }
            adminViewModel.viewModelScope.launch {

                onDefaultThread {
                    try {
                        while (true) {
                            if (usbDriverManager.mUsbDriver != null) {
                                PrintFeedDot(30)
                                val m_sbData = StringBuilder("testPrint:${mBinding.edtPrint.text}")


                                usbDriverManager.mUsbDriver?.write(PrintCmd.SetClean()) // 初始化，清理缓存
                                usbDriverManager.mUsbDriver?.write(PrintCmd.SetReadZKmode(0))
                                usbDriverManager.mUsbDriver?.write(PrintCmd.PrintString(m_sbData.toString(), 0))
                                usbDriverManager.mUsbDriver?.write(PrintCmd.PrintFeedline(5)) // 打印走纸2行
                            }
                        }
                    } catch (e: Exception) {

                    }
                }
            }
        }
    }


    var mUsbReceiver: BroadcastReceiver = object : BroadcastReceiver() {
        override fun onReceive(context: Context, intent: Intent) {
            val action = intent.action
            if (UsbManager.ACTION_USB_DEVICE_DETACHED == action) {
                val device = intent.getParcelableExtra<Parcelable>(UsbManager.EXTRA_DEVICE) as UsbDevice?
                if ((device!!.productId == 8211 && device.vendorId == 1305)
                    || (device.productId == 8213 && device.vendorId == 1305)
                ) {
                    usbDriverManager.mUsbDriver?.closeUsbDevice(device)
                }
            } else if (ACTION_USB_PERMISSION == action) synchronized(this) {
                val device = intent.getParcelableExtra<Parcelable>(UsbManager.EXTRA_DEVICE) as UsbDevice?
                if (intent.getBooleanExtra(UsbManager.EXTRA_PERMISSION_GRANTED, false)) {
                    if ((device!!.productId == 8211 && device.vendorId == 1305)
                        || (device.productId == 8213 && device.vendorId == 1305)
                    ) {
                        //赋权限以后的操作
                    }
                } else {
//                    Toast.makeText(MainActivity.this, "permission denied for device",
                    toast("permission denied for device")
                }
            }
        }
    }

    fun usbDriverCheck(): Int {
        var iResult = -1
        try {
            if (usbDriverManager.mUsbDriver?.isUsbPermission() == false) {
                val manager = requireActivity().getSystemService(Context.USB_SERVICE) as UsbManager?
                val deviceList = manager?.deviceList
                mUsbDevice = null
                val deviceIterator: MutableIterator<UsbDevice>? = deviceList?.values?.iterator()
                while (deviceIterator?.hasNext() == true) {
                    val device = deviceIterator.next()
                    if ((device.productId == 8211 && device.vendorId == 1305)
                        || (device.productId == 8213 && device.vendorId == 1305)
                    ) {
                        mUsbDevice = device
                        toast("DeviceClass:" + device.deviceClass + ";DeviceName:" + device.deviceName)
                    }
                }
                if (mUsbDevice != null) {
                    iResult = 1
                    if (usbDriverManager.mUsbDriver?.usbAttached(mUsbDevice) == true) {
                        if (usbDriverManager.mUsbDriver?.openUsbDevice(mUsbDevice) == true) iResult = 0
                    }
                }
            } else {
                if (usbDriverManager.mUsbDriver?.isConnected() == false) {
                    if (usbDriverManager.mUsbDriver?.openUsbDevice(mUsbDevice) == true) iResult = 0
                } else {
                    iResult = 0
                }
            }
        } catch (e: java.lang.Exception) {
        }

        return iResult
    }


}